﻿<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>制作树形导航菜单</title>
    <style type="text/css">
        body {
            margin: 0;
            padding: 0;
            font: 12px/1.5 Tahoma,Helvetica,Arial,sans-serif;
        }

        ul, li {
            margin: 0;
            padding: 0;
        }

        ul {
            list-style: none;
        }

        #menu_zzjs_net {
            margin: 10px;
            width: 200px;
            overflow: hidden;
        }

            #menu_zzjs_net li {
                line-height: 25px;
            }

            #menu_zzjs_net .rem {
                padding-left: 16px;
            }

            #menu_zzjs_net .add {
                background: url(/img/tree_20110125zzjs_net.gif) -4px -31px no-repeat;
            }

            #menu_zzjs_net .ren {
                background: url(/img/tree_20110125zzjs_net.gif) -4px -7px no-repeat;
            }

            #menu_zzjs_net li a {
                color: #666666;
                padding-left: 5px;
                outline: none;
                blr: expression(this.onFocus=this.blur());
            }

            #menu_zzjs_net li input {
                vertical-align: middle;
                margin-left: 5px;
            }

            #menu_zzjs_net .two {
                padding-left: 20px;
                display: none;
            }
    </style>


</head>
<body>
    <ul id="menu_zzjs_net">
        <li>
            <label><a href="javascript:;">泽惠果蔬配送中心</a></label>
            <ul class="two">
                <li>
                    <label><a href="javascript:;">水果分类</a></label>
                    <ul class="two">
                        <li>
                            <label><input type="checkbox" value="123456"><a href="javascript:;">苹果类</a></label>
                            <ul class="two">
                                <li><label><input type="checkbox" value="123456"><a href="javascript:;">青苹果</a></label></li>
                                <li>
                                    <label><input type="checkbox" value="123456"><a href="javascript:;">红苹果</a></label>
                                    <ul class="two">
                                        <li>
                                            <label><input type="checkbox" value="123456"><a href="javascript:;">红富士苹果</a></label>
                                            <ul class="two">
                                                <li><label><input type="checkbox" value="123456"><a href="javascript:;">水晶红富士苹果</a></label></li>
                                                <li><label><input type="checkbox" value="123456"><a href="javascript:;">优质红富士苹果</a></label></li>
                                            </ul>
                                        </li>
                                        <li><label><input type="checkbox" value="123456"><a href="javascript:;">冰糖心苹果</a></label></li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>
                    <label><a href="javascript:;">蔬菜分类</a></label>
                    <ul class="two">
                        <li><label><input type="checkbox" value="123456"><a href="javascript:;">西红柿</a></label></li>
                        <li><label><input type="checkbox" value="123456"><a href="javascript:;">西兰花</a></label></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>

    <script type="text/javascript">
        function addEvent(el, name, fn) {//绑定事件
            if (el.addEventListener) return el.addEventListener(name, fn, false);
            return el.attachEvent('on' + name, fn);
        }
        function nextnode(node) {//寻找下一个兄弟并剔除空的文本节点
            if (!node) return;
            if (node.nodeType == 1)
                return node;
            if (node.nextSibling)
                return nextnode(node.nextSibling);
        }
        function prevnode(node) {//寻找上一个兄弟并剔除空的文本节点
            if (!node) return;
            if (node.nodeType == 1)
                return node;
            if (node.previousSibling)
                return prevnode(node.previousSibling);
        }
        function parcheck(self, checked) {//递归寻找父亲元素，并找到input元素进行操作
            var par = prevnode(self.parentNode.parentNode.parentNode.previousSibling), parspar;
            if (par && par.getElementsByTagName('input')[0]) {
                par.getElementsByTagName('input')[0].checked = checked;
                parcheck(par.getElementsByTagName('input')[0], sibcheck(par.getElementsByTagName('input')[0]));
            }
        }
        function sibcheck(self) {//判断兄弟节点是否已经全部选中
            var sbi = self.parentNode.parentNode.parentNode.childNodes, n = 0;
            for (var i = 0; i < sbi.length; i++) {
                if (sbi[i].nodeType != 1)//由于孩子结点中包括空的文本节点，所以这里累计长度的时候也要算上去
                    n++;
                else if (sbi[i].getElementsByTagName('input')[0].checked)
                    n++;
            }
            return n == sbi.length ? true : false;
        }
        addEvent(document.getElementById('menu_zzjs_net'), 'click', function (e) {//绑定input点击事件，使用menu_zzjs_net根元素代理
            e = e || window.event;
            var target = e.target || e.srcElement;
            var tp = nextnode(target.parentNode.nextSibling);
            switch (target.nodeName) {
                case 'A'://点击A标签展开和收缩树形目录，并改变其样式会选中checkbox
                    if (tp && tp.nodeName == 'UL') {
                        if (tp.style.display != 'block') {
                            tp.style.display = 'block';
                            prevnode(target.parentNode.previousSibling).className = 'ren'
                        } else {
                            tp.style.display = 'none';
                            prevnode(target.parentNode.previousSibling).className = 'add'
                        }
                    }
                    break;
                case 'SPAN'://点击图标只展开或者收缩
                    var ap = nextnode(nextnode(target.nextSibling).nextSibling);
                    if (ap.style.display != 'block') {
                        ap.style.display = 'block';
                        target.className = 'ren'
                    } else {
                        ap.style.display = 'none';
                        target.className = 'add'
                    }
                    break;
                case 'INPUT'://点击checkbox，父亲元素选中，则孩子节点中的checkbox也同时选中，孩子结点取消父元素随之取消
                    if (target.checked) {
                        if (tp) {
                            var checkbox = tp.getElementsByTagName('input');
                            for (var i = 0; i < checkbox.length; i++)
                                checkbox[i].checked = true;
                        }
                    } else {
                        if (tp) {
                            var checkbox = tp.getElementsByTagName('input');
                            for (var i = 0; i < checkbox.length; i++)
                                checkbox[i].checked = false;
                        }
                    }
                    parcheck(target, sibcheck(target));//当孩子结点取消选中的时候调用该方法递归其父节点的checkbox逐一取消选中
                    break;
            }
        });
        window.onload = function () {//页面加载时给有孩子结点的元素动态添加图标
            var labels = document.getElementById('menu_zzjs_net').getElementsByTagName('label');
            for (var i = 0; i < labels.length; i++) {
                var span = document.createElement('span');
                span.style.cssText = 'display:inline-block;height:18px;vertical-align:middle;width:16px;cursor:pointer;';
                span.innerHTML = ' '
                span.className = 'add';
                if (nextnode(labels[i].nextSibling) && nextnode(labels[i].nextSibling).nodeName == 'UL')
                    labels[i].parentNode.insertBefore(span, labels[i]);
                else
                    labels[i].className = 'rem'
            }
        }
    </script>

</body>
</html>